﻿#include "EnemyModel.h"

using namespace Ogre;

EnemyModel::EnemyModel(Ogre::SceneManager * sm): mSceneMgr(sm),target(Ogre::Vector3(0,0,0))
{
	Initialization();
}

EnemyModel::~EnemyModel(void)
{
}

void EnemyModel::Initialization()
{
	mPlaneEntity = mSceneMgr->createEntity( "razor", "razor.mesh" );
	mPlaneEntity->setQueryFlags(0x1);
	mAttachedSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

	srand((unsigned)time(0));
	mAttachedSceneNode->setPosition( rand() % 200 - 100, 1000, -1000 );
//	mAttachedSceneNode->setDirection(0.0f, 1.0f ,0.0f );
	mAttachedSceneNode->attachObject(mPlaneEntity);
	mAttachedSceneNode->setScale(0.1,0.1,0.1);
	
	this->setTargetPostion(this->target);
	Ogre::Vector3 lengthVec = this->target - this->getPostion();
	this->setSpeed(lengthVec.length()/20);
	Ogre::Vector3 src = mAttachedSceneNode->getOrientation() * Ogre::Vector3::UNIT_Z;
	Ogre::Quaternion quat = src.getRotationTo(mDirection);
	this->setTargetOrientation(quat,0.01);
	
	setupThrusters();

	EnemyStatus = DIVING;
}

void EnemyModel::AddTime( Ogre::Real deltaTime )
{
	//this->mPlaneAnimState->addTime(deltaTime);
	updatePlane();
	PapaObject::AddTime(deltaTime);
}

//void EnemyModel::setOrbit(Ogre::Vector3 target)
//{
//	// create a 14 second animation with spline interpolation
//	anim = mSceneMgr->createAnimation("Path1", 14);
//	anim->setInterpolationMode(Animation::IM_SPLINE);
//
//	track = anim->createNodeTrack(1, mAttachedSceneNode);  // create a node track for our animation
//
//	// enter keyframes for our track to define a path for the light to follow
//	track->createNodeKeyFrame(2)->setTranslate(Vector3(0, 80, -50));
//
//	// create an animation state from the animation and enable it
//	mPlaneAnimState = mSceneMgr->createAnimationState("Path1");
//	mPlaneAnimState->setEnabled(true);
//}

bool equal(Ogre::Quaternion a, Ogre::Quaternion b)
{
	Ogre::Real zeroLimit = 0.001;
	if (abs(a.w-b.w)<zeroLimit && abs(a.x-b.x)<zeroLimit && abs(a.y-b.y)<zeroLimit && abs(a.z-b.z)<zeroLimit) return true;
	else return false;
}


void EnemyModel::updatePlane()
{
	Ogre::Vector3 lengthVec = this->target - this->getPostion();
	if (EnemyStatus == DIVING)
	{
		this->setTargetPostion(this->target);
		this->setSpeed(lengthVec.length()/10);
		Ogre::Vector3 src = mAttachedSceneNode->getOrientation() * Ogre::Vector3::UNIT_Z;
		Ogre::Quaternion quat = src.getRotationTo(mDirection);
		this->setTargetOrientation(quat,0.01);
		if(lengthVec.length() < 100)
		{
			EnemyStatus = TURNING;
			PRINT("EnemyStatus: "<<EnemyStatus);
			turnAround();
		}
	}
	else if (EnemyStatus == RETURNING)
	{
		this->setTargetPostion(this->ReDiveStart);
		Ogre::Vector3 ReturnVec = this->ReDiveStart - this->getPostion();
		this->setSpeed(lengthVec.length()/10);
		if(getPostion() == ReDiveStart)
		{
			EnemyStatus = REDIVETURNING;
			PRINT("EnemyStatus: "<<EnemyStatus);
		}
	}
	else if (EnemyStatus == TURNING)
	{
		Ogre::Vector3 src = mAttachedSceneNode->getOrientation() * Ogre::Vector3::UNIT_Z;
		this->setTargetPostion(this->getPostion()+src);
		Ogre::Vector3 src2 = mAttachedSceneNode->getOrientation() * Ogre::Vector3::UNIT_Z;
		Ogre::Quaternion quat = src2.getRotationTo(ReDiveStart-getPostion());
		this->setTargetOrientation(quat,3);
		if( equal(mAttachedSceneNode->getOrientation(),quat) )
		{
			EnemyStatus = RETURNING;
			PRINT("EnemyStatus: "<<EnemyStatus);
		}
	}
	else if (EnemyStatus == REDIVETURNING)
	{
		Ogre::Vector3 src = mAttachedSceneNode->getOrientation() * Ogre::Vector3::UNIT_Z;
		this->setTargetPostion(this->getPostion()+src);
		Ogre::Vector3 src2 = mAttachedSceneNode->getOrientation() * Ogre::Vector3::UNIT_Z;
		Ogre::Quaternion quat = src2.getRotationTo(target-getPostion());
		this->setTargetOrientation(quat,6);
		if( equal(mAttachedSceneNode->getOrientation(),quat) )
		{
			EnemyStatus = DIVING;
			PRINT("EnemyStatus: "<<EnemyStatus);
		}
	}
}

void EnemyModel::turnAround()
{
	int x = 0,z = 0;
	srand((unsigned)time(0));
	if(rand()%2 == 0) {
		x = 1000;
		z = rand()%2001 - 1000;
	} else {
		z = 1000;
		x = rand()%2001 - 1000;
	}
	ReDiveStart = Ogre::Vector3(x,1000,z);
	PRINT("ReDiveStart: "<<ReDiveStart);
}

void EnemyModel::setupThrusters()
{
	//创建粒子系统
	_thrusters = mSceneMgr->createParticleSystem( "ParticleSys1" );

	//设置粒子系统的纹理
	_thrusters ->setMaterialName( "Examples/Flare" );
	_thrusters ->setDefaultDimensions( 5, 5 );


	//设置点发射器1&2
	ParticleEmitter *emit1 = _thrusters ->addEmitter( "Point" );
	ParticleEmitter *emit2 = _thrusters ->addEmitter( "Point" );

	//设置发射器1的参数
	emit1->setAngle( Degree(3) );
	emit1->setTimeToLive( 0.1f );
	emit1->setEmissionRate( 70 );

	emit1->setParticleVelocity( 50 );

	emit1->setDirection( -Vector3::UNIT_Z);
	emit1->setColour( ColourValue::White, ColourValue::Red);        

	//设置发射器2的参数
	emit2->setAngle( Degree(3) );
	emit2->setTimeToLive( 0.1f );
	emit2->setEmissionRate( 70 );

	emit2->setParticleVelocity( 50 );

	emit2->setDirection( -Vector3::UNIT_Z );
	emit2->setColour( ColourValue::White, ColourValue::Red );

	//设置两个发射器位置
	emit1->setPosition( Vector3( 5.7f, 0.0f, 0.0f ) );
	emit2->setPosition( Vector3( -18.0f, 0.0f, 0.0f ) );

	//设置发射速度
	emit1->setParticleVelocity( 70 );
	emit2->setParticleVelocity( 70 );
	
	//把发射器挂接到飞机节点上。
	mAttachedSceneNode->createChildSceneNode( Vector3( 0.0f, 0.0f, -75.0f ) )->attachObject(_thrusters);
}

void EnemyModel::setTarget(Ogre::Vector3 t)
{
	target = t;
}